import time
import traceback
from socket import socket
from threading import Thread

import requests
from flask import session

import app.tasks
from app.iot_mqtt.iot_funciton import set_device_properties
from app.models import Role

from app.tasks import *

GAODE_KEY = 'aea2b5637a302fead60820d74b298964'  # 你的key
ADDRESS = '湖南省长沙市芙蓉区'  # 你的地址信息

DEFAULT_SETTINGS = {
    "roles": [
        {"id": "default", "name": "AI助手", "description": "乐于助人的AI助手",
         "system_prompt": "你是一个乐于助人的AI助手"},
        {"id": "coder", "name": "编程专家", "description": "擅长编程和技术问题的AI",
         "system_prompt": "你是一个专业的程序员，擅长Python、Java等多种编程语言，能够帮助解决各种技术问题"},
        {"id": "writer", "name": "作家", "description": "创意写作和故事创作",
         "system_prompt": "你是一个富有创造力的作家，擅长各种文学体裁的创作"}
    ],
    "current_role": "default",
    "current_conversation": None,
    "conversations": {},
    "settings": {
        "max_tokens": 512,
        "temperature": 0.7,
        "top_p": 1.0,
        "presence_penalty": 0.0,
        "frequency_penalty": 0.0
    }
}


def is_authenticated():
    # 示例逻辑，根据您的实际认证机制修改
    return 'user' in session  # 假设登录后将用户信息存入 session['user']


def init_session():
    """初始化session数据"""
    if 'app_data' not in session:
        session['app_data'] = DEFAULT_SETTINGS
        session.modified = True


# 存储客户端的最后活跃时间
client_last_active = {}
q = []


def check_client_activity():
    while True:
        current_time = time.time()
        inactive_clients = []
        for client in q:
            if client not in client_last_active or (current_time - client_last_active[client] > 60):  # 60秒无活动
                inactive_clients.append(client)
        for client in inactive_clients:
            if client in q:
                q.remove(client)
            if client in client_last_active:
                del client_last_active[client]
        time.sleep(30)  # 每30秒检查一次


# 高德地图API配置

def get_city_code():
    """获取城市编码"""
    url = 'https://restapi.amap.com/v3/geocode/geo'
    params = {
        'key': GAODE_KEY,
        'address': ADDRESS
    }
    response = requests.get(url, params=params)
    data = response.json()
    return data['geocodes'][0]['adcode']


def rule_executor():
    while True:
        try:
            from app.routes.control import auto_rules
            for rule_id, rule in auto_rules.items():
                if not rule['active']:
                    continue

                # 获取传感器数据（示例）
                sensor_value = get_sensor_data(rule['sensor'])

                # 条件判断
                condition_met = eval(
                    f"{sensor_value} {rule['operator']} {rule['threshold']}"
                )

                if condition_met:
                    execute_action(rule['action'])

            time.sleep(10)  # 每10秒检查一次
        except Exception as e:
            print(f"规则执行出错: {str(e)}")


def get_sensor_data(sensor_type):
    # 这里应该是实际获取传感器数据的逻辑
    # 示例返回随机数据
    import random
    if sensor_type == 'humidity':
        return random.uniform(30, 80)  # 湿度百分比
    elif sensor_type == 'temperature':
        return random.uniform(15, 35)  # 温度摄氏度
    return 0


device_states = {
    'water': 'false',
    'fan': 'false',
    'led': 'false',
    'soil': 'true'  # 土壤湿度状态保持不变
}


def execute_action(action):
    """
        执行阈值触发的动作
        支持的操作: water_on, water_off, fan_on, fan_off, led_on, led_off
    """
    global device_states
    if action == "water_on":
        device_states['water'] = 'true'
    elif action == "water_off":
        device_states['water'] = 'false'
    elif action == "fan_on":
        device_states['fan'] = 'true'
    elif action == "fan_off":
        device_states['fan'] = 'false'
    elif action == "led_on":
        device_states['led'] = 'true'
    elif action == "led_off":
        device_states['led'] = 'false'
    else:
        print(f"未知动作: {action}")
        return
    command = {
        "Switch": {
            "paras": {
                "led": device_states['led'],
                "soil": device_states['soil'],  # 土壤湿度状态保持不变
                "water": device_states['water'],
                "fan": device_states['fan']
            },
            "service_id": "mqtt",
            "command_name": "Switch"
        }
    }

    set_device_properties(command)
    print(f"执行动作: {action}")

    # 这里添加实际执行动作的逻辑，例如通过 MQTT 发送命令


# data_queue = {
#         "device_id": device_config["username"],
#         "server": f"{device_config['hostname']}:{device_config['port']}",
#         "protocol": device_config["protocol"],
#         "service_id": device_properties["services"][0]["service_id"],
#         "temperature": props["tem"],
#         "humidity": props["hum"],
#         "led_status": "开启" if props["led"] else "关闭",
#         "device_status": "在线" if props["stat"] else "离线"
#     }

def check_and_execute_rules():
    # 检查所有规则并执行符合条件的动作
    from app.routes.control import auto_rules
    from app.iot_mqtt.iot_funciton import data_queue

    if data_queue is None:
        print("队列为空 没有数据 请先更新数据")
    else:

        for rule in auto_rules:
            sensor_value = data_queue[-1][rule['sensor']]

            # 根据操作符比较
            if rule['operator'] == '>' and sensor_value > float(rule['threshold']):
                execute_action(rule['action'])
            elif rule['operator'] == '<' and sensor_value < float(rule['threshold']):
                execute_action(rule['action'])


from flask_apscheduler import APScheduler

scheduler = APScheduler()


def get_task_function(func_path):
    """动态导入任务函数"""
    module_path, func_name = func_path.rsplit('.', 1)
    module = importlib.import_module(module_path)
    return getattr(module, func_name)


import importlib
import traceback


def resolve_function_path(func_name):
    """
    解析函数路径，支持多种格式：
    1. 完整路径（如 'app.Ai_analyze.ai_function.analyze_data_task'）
    2. 函数名（如 'analyze_data_task'）
    """
    # 尝试直接使用传入的路径
    try:
        module_name, func_name_in_path = func_name.rsplit('.', 1)
        module = importlib.import_module(module_name)
        func = getattr(module, func_name_in_path)
        print(f"直接导入成功: {func_name}")
        return func_name  # 返回原始完整路径
    except (ValueError, ImportError, AttributeError):
        pass

    # 如果传入的是映射中的函数名
    if func_name in app.TASK_FUNCTIONS:
        func_path = app.TASK_FUNCTIONS[func_name]
        try:
            module_name, func_name_in_path = func_path.rsplit('.', 1)
            module = importlib.import_module(module_name)
            func = getattr(module, func_name_in_path)
            print(f"通过映射导入成功: {func_path}")
            return func_path
        except (ImportError, AttributeError) as e:
            print(f"映射导入失败: {e}")

    # 尝试自动解析
    for module_path in [
        "app.Ai_analyze.ai_function",
        "app.tasks",
        "app.scheduled_tasks"
    ]:
        try:
            module = importlib.import_module(module_path)
            if hasattr(module, func_name):
                func_path = f"{module_path}.{func_name}"
                print(f"自动解析成功: {func_path}")
                return func_path
        except ImportError:
            continue

    # 如果所有方法都失败，抛出异常
    raise ValueError(f"无法解析函数路径: {func_name}")


def add_new_job(job_id, func_name, trigger, **trigger_args):
    """动态添加新任务"""
    try:
        print(f"添加任务: {job_id}, {func_name}, {trigger}, {trigger_args}")

        # 解析函数路径
        # func_path = resolve_function_path(func_name)
        # print(f"解析后的函数路径: {func_path}")

        # 验证函数是否存在
        # module_name, func_name_in_path = func_path.rsplit('.', 1)
        # print(func_name_in_path)
        # module = importlib.import_module(module_name)
        # func = getattr(module, func_name_in_path)
        # print(f"成功导入函数: {func}")
        # print(type(func))

        # 添加任务
        scheduler.add_job(
            id=job_id,
            func=func_name,  # 使用字符串路径
            trigger=trigger,
            **trigger_args,
            replace_existing=True
        )
        print(f"任务添加成功: {job_id}")
        return True
    except Exception as e:
        print(f"添加任务失败: {e}")
        traceback.print_exc()
        raise


def remove_job(job_id):
    """删除任务"""
    scheduler.remove_job(job_id)


def get_all_jobs():
    """获取所有计划任务"""
    return scheduler.get_jobs()

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

SMTP_SERVER = 'smtp.163.com'
SMTP_PORT = 25
SENDER_EMAIL = 'qinzhaojun2022@163.com'  # 替换为你的 163 邮箱
SENDER_PASSWORD = "HBkkfrMcvxiWcUEX"  # 替换为 163 邮箱授权码

def send_email(recipients, subject, body):
    msg = MIMEMultipart()
    msg['From'] = SENDER_EMAIL
    msg['To'] = ", ".join(recipients)
    msg['Subject'] = subject
    msg.attach(MIMEText(body, 'plain', 'utf-8'))

    try:
        server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
        server.starttls()
        server.login(SENDER_EMAIL, SENDER_PASSWORD)
        server.sendmail(SENDER_EMAIL, recipients, msg.as_string())
        server.quit()
        print("邮件发送成功")
    except Exception as e:
        print(f"邮件发送失败: {e}")
        raise